#include <pthread.h>
#include <string.h>

#include "psd_settings.h"
#include "psd_depot_settings.h"
#include "psd_logger.h"

static psdSettings *depot_settings = NULL;
static pthread_mutex_t depot_settings_lock;

int psd_depot_settings_init() {

	if (pthread_mutex_init(&depot_settings_lock, 0) != 0) {
		psd_err(0, "couldn't initialize the depot settings lock");
		goto error_exit;
	}

	depot_settings = psd_settings_alloc();
	if (!depot_settings) {
		psd_err(0, "couldn't allocate depot settings");
		goto error_exit_mutex;
	}

	return 0;

error_exit_mutex:
	pthread_mutex_destroy(&depot_settings_lock);
error_exit:
	return -1;
}

void print_depot_settings() {
	pthread_mutex_lock(&depot_settings_lock);
	{
		psd_settings_print(depot_settings);
	}
	pthread_mutex_unlock(&depot_settings_lock);
}

psdSettings *psd_depot_settings() {
	psdSettings *ret_settings;

	pthread_mutex_lock(&depot_settings_lock);
	{
		ret_settings = depot_settings;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return ret_settings;
}

int psd_set_depot_settings(psdSettings *settings) {
	pthread_mutex_lock(&depot_settings_lock);
	{
		depot_settings = settings;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return 0;
}

int psd_depot_settings_get(const char *section, const char *option, char **value) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get_2(depot_settings, section, option, value);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_int(const char *section, const char *option, int *value) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get_int_2(depot_settings, section, option, value);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_bool(const char *section, const char *option, int *value) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get_bool_2(depot_settings, section, option, value);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_list(const char *section, const char *option, char ***value, int *count) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get_list_2(depot_settings, section, option, value, count);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_set(const char *section, const char *option, char *value) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_set_2(depot_settings, section, option, value);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_set_int(const char *section, const char *option, int value) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_set_int_2(depot_settings, section, option, value);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_set_bool(const char *section, const char *option, int value) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_set_bool_2(depot_settings, section, option, value);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_set_list(const char *section, const char *option, char * const *value, int count) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_set_list_2(depot_settings, section, option, value, count);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_set_range(const char *section, const char *option, int min, int max) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_set_range_2(depot_settings, section, option, min, max);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_range(const char *section, const char *option, int *min, int *max) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get_range_2(depot_settings, section, option, min, max);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}


int psd_depot_settings_get_3(const char *section1, const char *section2, const char *option, char **value) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get_3(depot_settings, section1, section2, option, value);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_int_3(const char *section1, const char *section2, const char *option, int *value) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get_int_3(depot_settings, section1, section2, option, value);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_bool_3(const char *section1, const char *section2, const char *option, int *value) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get_bool_3(depot_settings, section1, section2, option, value);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_list_3(const char *section1, const char *section2, const char *option, char ***value, int *count) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get_list_3(depot_settings, section1, section2, option, value, count);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_range_3(const char *section1, const char *section2, const char *option, int *min, int *max) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get_range_3(depot_settings, section1, section2, option, min, max);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}


int psd_depot_settings_get_4(const char *section1, const char *section2, const char *section3, const char *option, char **value) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get_4(depot_settings, section1, section2, section3, option, value);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_int_4(const char *section1, const char *section2, const char *section3, const char *option, int *value) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get_int_4(depot_settings, section1, section2, section3, option, value);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_bool_4(const char *section1, const char *section2, const char *section3, const char *option, int *value) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get_bool_4(depot_settings, section1, section2, section3, option, value);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_list_4(const char *section1, const char *section2, const char *section3, const char *option, char ***value, int *count) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get_list_4(depot_settings, section1, section2, section3, option, value, count);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_range_4(const char *section1, const char *section2, const char *section3, const char *option, int *min, int *max) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings) 
			n = psd_settings_get_range_4(depot_settings, section1, section2, section3, option, min, max);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_section(const char *section, psdSettings **settings) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings) 
			n = psd_settings_get_group(depot_settings, section, settings);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;

}

int psd_depot_settings_get_subsection(const char *section, const char *subsection, psdSettings **settings) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings) 
			n = psd_settings_get_group_2(depot_settings, section, subsection, settings);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_subsubsection(const char *section, const char *subsection, const char *subsubsection, psdSettings **settings) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings) 
			n = psd_settings_get_group_3(depot_settings, section, subsection, subsubsection, settings);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}

int psd_depot_settings_get_1(const char *option, char **value) {
	int n;

	pthread_mutex_lock(&depot_settings_lock);
	{
		if (depot_settings)
			n = psd_settings_get(depot_settings, option, value);
		else
			n = -1;
	}
	pthread_mutex_unlock(&depot_settings_lock);

	return n;
}


